from flask import Blueprint, render_template, request, jsonify, current_app, session
from flask_login import current_user
import json
import re
import time
import html
import datetime
from bson.objectid import ObjectId
import jsbeautifier
import cssbeautifier
import html.parser
# 导入Python代码格式化相关的包
try:
    import autopep8
    import black
    PYTHON_FORMATTERS_AVAILABLE = True
except ImportError:
    PYTHON_FORMATTERS_AVAILABLE = False

dev_tools_bp = Blueprint('dev_tools', __name__, url_prefix='/tools/dev')


@dev_tools_bp.route('/')
def index():
    """开发工具首页"""
    tools = [
        {
            'name': 'JSON 格式化工具',
            'description': '格式化、压缩、验证 JSON 数据',
            'icon': 'fa-code',
            'url': '/tools/dev/json_formatter'
        },
        {
            'name': '代码格式化工具',
            'description': '格式化 HTML、CSS、JavaScript 代码',
            'icon': 'fa-indent',
            'url': '/tools/dev/code_formatter'
        },
        {
            'name': '正则表达式测试器',
            'description': '测试和验证正则表达式',
            'icon': 'fa-search',
            'url': '/tools/dev/regex_tester'
        },
        {
            'name': '时间戳转换器',
            'description': '在时间戳和日期字符串之间转换',
            'icon': 'fa-clock',
            'url': '/tools/dev/timestamp_converter'
        }
    ]
    
    return render_template('tools/dev/index.html', tools=tools)


@dev_tools_bp.route('/json_formatter')
def json_formatter():
    """渲染JSON格式化工具页面"""
    return render_template('tools/dev/json_formatter.html')


@dev_tools_bp.route('/json_formatter', methods=['POST'])
def process_json():
    """处理JSON格式化请求"""
    data = request.get_json()
    
    if not data:
        return jsonify({
            'error': 400,
            'message': '缺少必要参数',
            'body': {}
        })
    
    json_str = data.get('json_string', '')
    action = data.get('action', 'format')  # 默认为格式化
    indent = data.get('indent', 4)  # 获取缩进设置
    sort_keys = data.get('sort_keys', False)  # 获取是否按键排序
    
    if not json_str:
        return jsonify({
            'error': 400,
            'message': 'JSON字符串不能为空',
            'body': {}
        })
    
    try:
        # 首先解析JSON检查有效性
        parsed_json = json.loads(json_str)
        
        if action == 'format':
            # 使用indent参数格式化，并根据sort_keys决定是否排序
            result = json.dumps(parsed_json, ensure_ascii=False, indent=indent, sort_keys=sort_keys)
        elif action == 'minify':
            # 不使用缩进，压缩JSON，仍然根据sort_keys决定是否排序
            result = json.dumps(parsed_json, ensure_ascii=False, separators=(',', ':'), sort_keys=sort_keys)
        elif action == 'validate':
            # 仅验证，返回原JSON
            result = json_str
        else:
            return jsonify({
                'error': 400,
                'message': '不支持的操作类型',
                'body': {}
            })
        
        return jsonify({
            'error': 0,
            'message': '操作成功',
            'body': {
                'result': result
            }
        })
    
    except json.JSONDecodeError as e:
        # JSON解析错误
        return jsonify({
            'error': 400,
            'message': f'无效的JSON格式: {str(e)}',
            'body': {}
        })


@dev_tools_bp.route('/code_formatter')
def code_formatter():
    """渲染代码格式化工具页面"""
    return render_template('tools/dev/code_formatter.html')


@dev_tools_bp.route('/code_formatter', methods=['POST'])
def process_code():
    """处理代码格式化请求"""
    data = request.get_json()
    
    if not data:
        return jsonify({
            'error': 400,
            'message': '缺少必要参数',
            'body': {}
        })
    
    code = data.get('code', '')
    language = data.get('language', 'javascript')  # 默认为JavaScript
    indent = data.get('indent', 4)  # 默认缩进4个空格
    
    # 其他可选参数
    insert_spaces = data.get('insert_spaces', True)
    bracket_spacing = data.get('bracket_spacing', True)
    semicolons = data.get('semicolons', True)
    single_quote = data.get('single_quote', False)
    trailing_commas = data.get('trailing_commas', False)
    
    if not code:
        return jsonify({
            'error': 400,
            'message': '代码不能为空',
            'body': {}
        })
    
    try:
        result = ""
        message = ""
        
        # 根据不同语言使用不同的格式化方法
        if language == 'javascript' or language == 'typescript':
            # 使用jsbeautifier格式化JavaScript/TypeScript
            js_options = {
                'indent_size': indent,
                'indent_char': ' ' if insert_spaces else '\t',
                'space_in_empty_paren': bracket_spacing,
                'space_in_paren': bracket_spacing,
                'brace_style': 'collapse',
                'preserve_newlines': True,
                'max_preserve_newlines': 2,
                'wrap_line_length': 0,
                'end_with_newline': True
            }
            result = jsbeautifier.beautify(code, js_options)
            
        elif language == 'json':
            # 使用Python内置json模块格式化JSON
            try:
                parsed_json = json.loads(code)
                result = json.dumps(parsed_json, ensure_ascii=False, indent=indent)
            except json.JSONDecodeError as e:
                return jsonify({
                    'error': 400,
                    'message': f'无效的JSON格式: {str(e)}',
                    'body': {}
                })
                
        elif language == 'css':
            # 使用cssbeautifier格式化CSS
            css_options = {
                'indent_size': indent,
                'indent_char': ' ' if insert_spaces else '\t'
            }
            result = cssbeautifier.beautify(code, css_options)
            
        elif language == 'html' or language == 'xml':
            # HTML/XML格式化功能
            # 这里是简单实现，真实环境可能需要更复杂的HTML格式化库
            def add_indent(s, level):
                lines = s.split('\n')
                return '\n'.join(' ' * (level * indent) + line for line in lines)
            
            # 简单的HTML标签匹配和缩进处理
            indentation_level = 0
            formatted_lines = []
            
            # 简单HTML格式化
            # 注意：这只是一个基本实现，真实项目中应使用专业HTML格式化库
            for line in code.split('\n'):
                line = line.strip()
                if not line:
                    continue
                    
                # 闭合标签减少缩进
                close_match = re.match(r'^</\w+>', line)
                if close_match:
                    indentation_level = max(0, indentation_level - 1)
                
                # 添加带缩进的行
                formatted_lines.append(' ' * (indentation_level * indent) + line)
                
                # 开放标签增加缩进，但自闭合标签不增加
                if '<' in line and '>' in line and not line.strip().endswith('/>') and not line.strip().startswith('</'):
                    indentation_level += 1
            
            result = '\n'.join(formatted_lines)
            message = "HTML/XML格式化是基础实现，复杂文档可能需要专业工具"
            
        elif language == 'python':
            # 尝试使用专业Python格式化库
            try:
                if PYTHON_FORMATTERS_AVAILABLE:
                    # 首先尝试使用black库（更严格的格式化）
                    try:
                        # 创建black的格式化模式
                        mode = black.FileMode(line_length=88)
                        result = black.format_str(code, mode=mode)
                        message = "使用Black格式化完成"
                    except Exception as black_error:
                        # 如果black出错，尝试使用autopep8
                        try:
                            # 配置autopep8选项
                            options = {
                                'aggressive': 1,  # 格式化级别
                                'max_line_length': 88,
                                'indent_size': indent
                            }
                            result = autopep8.fix_code(code, options=options)
                            message = "使用Autopep8格式化完成"
                        except Exception as autopep_error:
                            # 两者都失败，使用基本格式化
                            raise Exception(f"Black错误: {str(black_error)}, Autopep8错误: {str(autopep_error)}")
                else:
                    # 使用基本的缩进处理
                    lines = code.split('\n')
                    formatted_lines = []
                    current_indent = 0
                    
                    for line in lines:
                        stripped = line.strip()
                        
                        # 空行保持不变
                        if not stripped:
                            formatted_lines.append('')
                            continue
                        
                        # 检查是否需要减少缩进
                        if stripped.startswith(('else:', 'elif', 'except:', 'finally:')):
                            current_indent = max(0, current_indent - 1)
                        
                        # 添加当前缩进
                        formatted_lines.append(' ' * (current_indent * indent) + stripped)
                        
                        # 检查是否需要增加缩进
                        if stripped.endswith((':',)):
                            current_indent += 1
                    
                    result = '\n'.join(formatted_lines)
                    message = "使用基本缩进格式化完成（完整格式化需要安装autopep8或black库）"
            except Exception as e:
                # 格式化过程中的异常，回退到基本格式化
                lines = code.split('\n')
                formatted_lines = []
                current_indent = 0
                
                for line in lines:
                    stripped = line.strip()
                    
                    # 空行保持不变
                    if not stripped:
                        formatted_lines.append('')
                        continue
                    
                    # 检查是否需要减少缩进
                    if stripped.startswith(('else:', 'elif', 'except:', 'finally:')):
                        current_indent = max(0, current_indent - 1)
                    
                    # 添加当前缩进
                    formatted_lines.append(' ' * (current_indent * indent) + stripped)
                    
                    # 检查是否需要增加缩进
                    if stripped.endswith((':',)):
                        current_indent += 1
                
                result = '\n'.join(formatted_lines)
                message = f"高级格式化失败，使用基本缩进格式化 - 错误: {str(e)}"
        
        else:
            # 其他语言目前不支持，返回原始代码
            result = code
            message = f"暂不支持{language}语言的完整格式化，仅返回原始代码"
        
        return jsonify({
            'error': 0,
            'message': '格式化成功',
            'body': {
                'result': result,
                'message': message
            }
        })
        
    except Exception as e:
        # 处理格式化过程中的异常
        return jsonify({
            'error': 500,
            'message': f'格式化过程发生错误: {str(e)}',
            'body': {}
        })


@dev_tools_bp.route('/regex_tester', methods=['GET', 'POST'])
def regex_tester():
    """正则表达式测试器"""
    if request.method == 'POST':
        try:
            # 从表单数据中获取参数，而不是JSON
            pattern = request.form.get('pattern', '')
            test_string = request.form.get('string', '')
            
            # 记录接收到的表单数据
            current_app.logger.info(f"接收到的表单数据: {dict(request.form)}")
            
            # 获取标志位参数，支持"true"字符串和真值
            ignore_case = request.form.get('ignoreCase') in ['true', True, 'True', '1', 1]
            multiline = request.form.get('multiline') in ['true', True, 'True', '1', 1]
            dot_all = request.form.get('dotAll') in ['true', True, 'True', '1', 1]
            
            # 记录转换后的布尔值
            current_app.logger.info(f"转换后的标志: ignore_case={ignore_case}, multiline={multiline}, dot_all={dot_all}")
            
            if not pattern:
                return jsonify({'error': 1, 'message': '正则表达式不能为空'}), 400
            
            # 处理正则表达式标志
            regex_flags = 0
            if ignore_case:
                regex_flags |= re.IGNORECASE
            if multiline:
                regex_flags |= re.MULTILINE
            if dot_all:
                regex_flags |= re.DOTALL
            
            # 记录将要编译的正则表达式
            current_app.logger.info(f"尝试编译正则表达式: {pattern}")
            
            # 预处理正则表达式，修复常见问题
            processed_pattern = pattern
            
            # 检查是否是常见的邮箱正则表达式
            is_email_pattern = '@' in pattern and ('\\w' in pattern or '\w' in pattern) and ('\\.' in pattern or '\.' in pattern)
            if is_email_pattern:
                current_app.logger.info("检测到可能是邮箱匹配模式")
                
                # 直接修复常见的问题模式
                if '\\w-\\.' in processed_pattern:
                    processed_pattern = processed_pattern.replace('\\w-\\.', '\\w\\.-')
                    current_app.logger.info(f"替换 \\w-\\. 为 \\w\\.-: {processed_pattern}")
                
                if '\\w-.' in processed_pattern:
                    processed_pattern = processed_pattern.replace('\\w-.', '\\w\\.-')
                    current_app.logger.info(f"替换 \\w-. 为 \\w\\.-: {processed_pattern}")
                
                # 其他类似的模式
                processed_pattern = re.sub(r'\[(\\w)-(\\.)\]', r'[\1\2-]', processed_pattern)
                processed_pattern = re.sub(r'\[(\\w)-(\.)\]', r'[\1\2-]', processed_pattern)
                
                # 如果仍然有问题，可以尝试使用我们推荐的邮箱正则表达式
                email_pattern_fixed = r'[\w\.-]+@([\w\.-]+)\.[\w\.-]{2,6}'
                
                # 如果原始正则表达式以^开头且以$结尾，提供一个备选不带锚点的版本
                if processed_pattern.startswith('^') and processed_pattern.endswith('$'):
                    email_pattern_no_anchors = processed_pattern[1:-1]
                    current_app.logger.info(f"创建不带锚点的版本: {email_pattern_no_anchors}")
            
            # 尝试编译正则表达式
            try:
                current_app.logger.info(f"尝试编译处理后的正则表达式: {processed_pattern}")
                regex = re.compile(processed_pattern, regex_flags)
                current_app.logger.info("正则表达式编译成功")
                
                # 查找匹配
                matches = []
                
                # 记录正则表达式和测试字符串
                current_app.logger.info(f"进行匹配，正则表达式={regex.pattern}，测试字符串={test_string}")
                
                # 尝试直接使用search检查是否有匹配
                search_result = regex.search(test_string)
                if search_result:
                    current_app.logger.info(f"search方法找到匹配: {search_result.group()}")
                else:
                    current_app.logger.info("search方法未找到匹配")
                
                # 使用finditer获取所有匹配
                for match in regex.finditer(test_string):
                    match_info = {
                        'start': match.start(),
                        'end': match.end(),
                        'group': match.group(),
                        'groups': match.groups()
                    }
                    matches.append(match_info)
                    current_app.logger.info(f"找到匹配: {match_info}")
                
                current_app.logger.info(f"找到 {len(matches)} 个匹配项")
                
                # 如果没有匹配但看起来像是邮箱，尝试使用推荐的正则表达式
                if len(matches) == 0 and is_email_pattern and '@' in test_string and '.' in test_string:
                    current_app.logger.info("测试字符串看起来像邮箱但未匹配成功，尝试推荐的正则表达式")
                    
                    try:
                        # 使用推荐的邮箱模式尝试匹配
                        fixed_matches = list(re.finditer(email_pattern_fixed, test_string, regex_flags))
                        current_app.logger.info(f"使用推荐的邮箱模式匹配结果: {len(fixed_matches)}个匹配")
                        
                        # 如果有锚点且无匹配，尝试不带锚点的版本
                        if len(fixed_matches) == 0 and pattern.startswith('^') and pattern.endswith('$'):
                            current_app.logger.info("尝试使用不带锚点的版本")
                            no_anchors_pattern = pattern[1:-1]  # 移除^和$
                            current_app.logger.info(f"不带锚点的正则表达式: {no_anchors_pattern}")
                            
                            try:
                                no_anchors_regex = re.compile(no_anchors_pattern.replace('\\w-\\.', '\\w\\.-').replace('\\w-.', '\\w\\.-'), regex_flags)
                                no_anchors_matches = list(re.finditer(no_anchors_regex, test_string, regex_flags))
                                current_app.logger.info(f"不带锚点的匹配结果: {len(no_anchors_matches)}个匹配")
                                
                                if len(no_anchors_matches) > 0:
                                    current_app.logger.info("不带锚点的版本成功匹配")
                                    # 返回匹配结果，并建议使用不带锚点的版本
                                    return jsonify({
                                        'error': 0, 
                                        'valid': True,
                                        'matches': [{
                                            'start': match.start(),
                                            'end': match.end(),
                                            'group': match.group(),
                                            'groups': match.groups()
                                        } for match in no_anchors_matches],
                                        'match_count': len(no_anchors_matches),
                                        'suggestion': {
                                            'message': '您的正则表达式使用了^和$锚点，要求从字符串开头匹配到结尾。您的文本中的邮箱不在开头/结尾位置，建议使用不带锚点的版本:',
                                            'pattern': no_anchors_pattern.replace('\\w-\\.', '\\w\\.-').replace('\\w-.', '\\w\\.-')
                                        }
                                    })
                            except Exception as e:
                                current_app.logger.error(f"尝试不带锚点的版本时出错: {str(e)}")
                        
                        if fixed_matches:
                            current_app.logger.info("推荐版本成功匹配，建议使用推荐版本")
                            # 向用户推荐更好的邮箱正则表达式
                            return jsonify({
                                'error': 0, 
                                'valid': True,
                                'matches': [{
                                    'start': match.start(),
                                    'end': match.end(),
                                    'group': match.group(),
                                    'groups': match.groups()
                                } for match in fixed_matches],
                                'match_count': len(fixed_matches),
                                'suggestion': {
                                    'message': '当前正则表达式虽然有效，但无法匹配这个邮箱，建议使用以下改进版本:',
                                    'pattern': email_pattern_fixed
                                }
                            })
                        else:
                            # 分析可能的原因
                            reasons = []
                            if '^' in pattern:
                                reasons.append("正则表达式以^开头，要求匹配必须从字符串开头开始，但邮箱地址前面有其他文本")
                            if '$' in pattern:
                                reasons.append("正则表达式以$结尾，要求匹配必须在字符串结尾结束，但邮箱地址后面可能有其他文本")
                            if '{2,4}' in pattern:
                                reasons.append("顶级域名长度限制为2-4个字符，可能过于严格，建议使用{2,6}")
                            
                            reason_text = "，".join(reasons) if reasons else "正则表达式可能过于严格或复杂"
                            
                            # 构建一个简单的通用邮箱正则表达式
                            simple_email_regex = r'[\w\.-]+@[\w\.-]+\.\w+'
                            
                            try:
                                simple_matches = list(re.finditer(simple_email_regex, test_string, regex_flags))
                                if simple_matches:
                                    return jsonify({
                                        'error': 0,
                                        'valid': True,
                                        'matches': [{
                                            'start': match.start(),
                                            'end': match.end(),
                                            'group': match.group(),
                                            'groups': match.groups()
                                        } for match in simple_matches],
                                        'match_count': len(simple_matches),
                                        'suggestion': {
                                            'message': f'您的正则表达式无法匹配文本中的邮箱，可能原因：{reason_text}。建议使用以下简化版本:',
                                            'pattern': simple_email_regex
                                        }
                                    })
                            except Exception as e:
                                current_app.logger.error(f"尝试简单邮箱正则表达式时出错: {str(e)}")
                    except Exception as e:
                        current_app.logger.error(f"尝试使用推荐模式匹配时出错: {str(e)}")
                
                # 返回常规匹配结果
                return jsonify({
                    'error': 0, 
                    'valid': True,
                    'matches': matches,
                    'match_count': len(matches)
                })
                
            except re.error as e:
                # 提供友好的错误消息
                error_detail = str(e)
                friendly_message = "正则表达式语法错误"
                
                # 根据错误类型提供具体提示
                if "unterminated character set" in error_detail:
                    friendly_message = "字符集没有正确闭合，请检查 [ ] 是否配对"
                elif "unbalanced parenthesis" in error_detail:
                    friendly_message = "括号没有正确闭合，请检查 ( ) 是否配对"
                elif "bad escape" in error_detail:
                    friendly_message = "无效的转义序列，在Python中特殊字符如\\w需要使用\\\\w表示"
                elif "nothing to repeat" in error_detail:
                    friendly_message = "重复操作符（如 *、+、?）前面没有有效的表达式"
                elif "multiple repeat" in error_detail:
                    friendly_message = "重复的量词，不能连续使用多个重复操作符"
                elif "bad character range" in error_detail:
                    friendly_message = "无效的字符范围。字符类中的连字符(-)用于表示范围，如[a-z]。如果要匹配连字符本身，应将其放在字符类的开头或结尾，如[-abc]或[abc-]。对于邮箱匹配，使用[\\w\\.-]而不是[\\w-\\.]"
                
                error_msg = f'{friendly_message}: {error_detail}'
                current_app.logger.error(error_msg)
                return jsonify({
                    'error': 1, 
                    'message': error_msg,
                    'valid': False
                }), 400
                
        except Exception as e:
            error_msg = f'处理错误: {str(e)}'
            current_app.logger.error(error_msg)
            return jsonify({'error': 1, 'message': error_msg}), 500
    
    return render_template('tools/dev/regex_tester.html')


@dev_tools_bp.route('/timestamp_converter', methods=['GET', 'POST'])
def timestamp_converter():
    """时间戳转换器"""
    if request.method == 'POST':
        try:
            data = request.json
            value = data.get('value', '')
            conversion_type = data.get('type', 'to_date')  # to_date 或 to_timestamp
            format_str = data.get('format', '%Y-%m-%d %H:%M:%S')
            
            if not value:
                return jsonify({'error': 1, 'message': '输入值不能为空'}), 400
            
            if conversion_type == 'to_date':
                # 时间戳转日期字符串
                try:
                    timestamp = float(value)
                    dt = datetime.datetime.fromtimestamp(timestamp)
                    date_str = dt.strftime(format_str)
                    return jsonify({
                        'error': 0, 
                        'result': date_str,
                        'timestamp': timestamp,
                        'iso': dt.isoformat()
                    })
                except ValueError:
                    return jsonify({'error': 1, 'message': '无效的时间戳值'}), 400
                    
            elif conversion_type == 'to_timestamp':
                # 日期字符串转时间戳
                try:
                    dt = datetime.datetime.strptime(value, format_str)
                    timestamp = dt.timestamp()
                    return jsonify({
                        'error': 0, 
                        'result': timestamp,
                        'date': value,
                        'iso': dt.isoformat()
                    })
                except ValueError:
                    return jsonify({'error': 1, 'message': f'无效的日期格式，应为 {format_str}'}), 400
            else:
                return jsonify({'error': 1, 'message': '不支持的转换类型'}), 400
                
        except Exception as e:
            return jsonify({'error': 1, 'message': f'处理错误: {str(e)}'}), 500
    
    return render_template('tools/dev/timestamp_converter.html') 